
/* experfect.cpp: Pixel-perfect collision.
   Public domain, Connelly Barnes 2002. */

#include <allegro.h>
#include <math.h>

#define max(a, b) (((a) > (b)) ? (a): (b))
#define min(a, b) (((a) < (b)) ? (a): (b))

int collide_detect(int xmin1, int ymin1, BITMAP *sprite1, int xmin2, int ymin2, BITMAP *sprite2) {
  int xmax1 = xmin1 + sprite1->w, ymax1 = ymin1 + sprite1->h;
  int xmax2 = xmin2 + sprite2->w, ymax2 = ymin2 + sprite2->h;
  int xmin = max(xmin1, xmin2);
  int ymin = max(ymin1, ymin2);
  int xmax = min(xmax1, xmax2);
  int ymax = min(ymax1, ymax2);
  if (xmax <= xmin || ymax <= ymin) { return 0; }
  int mask1 = bitmap_mask_color(sprite1);
  int mask2 = bitmap_mask_color(sprite2);
  for (int y = ymin; y < ymax; y++) {
    for (int x = xmin; x < xmax; x++) {
      int x1 = x - xmin1, y1 = y - ymin1;
      int x2 = x - xmin2, y2 = y - ymin2;
      int color1 = getpixel(sprite1, x1, y1);
      int color2 = getpixel(sprite2, x2, y2);
      if (color1 != mask1 && color2 != mask2) { 
		  if(color2 == makecol(255,0,0)) return 1;
		  if(color2 == makecol(0,0,255)) return 2;
		  else return 3;
		   }
    }
  }
  return 0;
}

void clip(double &value, double min, double max) {
  if (value < min) { value = min; }
  else if (value > max) { value = max; }
}

int scr_width = 640, scr_height = 480;

volatile long elapsed_time = 0;
void __inc_elapsed_time() { elapsed_time++; }
END_OF_FUNCTION(__inc_elapsed_time);

double frame_time = 0, last_time, dt;

void init_all();
int main() {
  init_all();
  BITMAP *buffer = create_bitmap(scr_width, scr_height);
  BITMAP *sprite1 = load_bitmap("colisao.bmp", 0);
  BITMAP *sprite2 = load_bitmap("sprite2.bmp", 0);

  /* (x1, y1, sprite1) represents the player
     (x2, y2, sprite2) represents the spider */

  double x1 = 200, y1 = 100;
  double x2 = 200, y2 = -200;
  while (!key[KEY_ESC]) {
    last_time = frame_time;
    frame_time = elapsed_time / 1000.0;
    dt = frame_time - last_time;

    if (key[KEY_RIGHT]) { x1 += 200 * dt; }
    if (key[KEY_LEFT])  { x1 -= 200 * dt; }
    if (key[KEY_UP])    { y1 -= 200 * dt; }
    if (key[KEY_DOWN])  { y1 += 200 * dt; }

	if (key[KEY_D]) { x2 += 200 * dt; }
    if (key[KEY_A])  { x2 -= 200 * dt; }
    if (key[KEY_W])    { y2 -= 200 * dt; }
    if (key[KEY_S])  { y2 += 200 * dt; }

    clip(x1, 0, scr_width - sprite1->w);
    clip(y1, 0, scr_height - sprite1->h);

    //x2 = sin(frame_time) * 100 + 200;

    int collided = collide_detect(int(x1), int(y1), sprite1, int(x2), int(y2), sprite2);
    switch (collided) {
	  case 0 :
		  clear(buffer);
		  y1 = y1 +1;
		  
	  case 1:
		clear(buffer);
		  break;
	  case 2:
			y1 = y1 + 1 ;
			clear(buffer);
			break;
	  default:
			y1 = y1 + 1 ;
			clear(buffer);
      
    }

    textprintf_ex(buffer, font, 10, 10, makecol(255, 255, 255), -1, "Pixel-perfect collision detection:");
    textprintf_ex(buffer, font, 10, 30, makecol(192, 192, 192), -1, "  Use arrow keys to move ship");
    textprintf_ex(buffer, font, 10, 40, makecol(192, 192, 192), -1, "  Screen turns red when objects collide");

    draw_sprite(buffer, sprite1, int(x1), int(y1));
    draw_sprite(buffer, sprite2, int(x2), int(y2));

    blit(buffer, screen, 0, 0, 0, 0, buffer->w, buffer->h);
  }
  return 0;
}

int depth_select(int depth) {
  set_color_depth(depth);
  return !set_gfx_mode(GFX_AUTODETECT, scr_width, scr_height, 0, 0);
}

void init_all() {
  allegro_init();

  install_keyboard();
  install_timer();

  LOCK_VARIABLE(elapsed_time);
  LOCK_FUNCTION(__inc_elapsed_time);
  install_int_ex(__inc_elapsed_time, BPS_TO_TIMER(1000));

  depth_select(32) || depth_select(24) || depth_select(16) || depth_select(15);
}

END_OF_MAIN();
